"""
    create by IAmFiveHigh on 2024/5/24
"""
from functools import reduce
from operator import mul

from LA.Matrix import Matrix
from LA.Vector import Vector
from LA.__globals import is_zero


def det(matrix: 'Matrix') -> float:
    if matrix.col_num() != matrix.row_num():
        raise Exception(f"Error: 矩阵{matrix}不是一个方阵")

    m = [Vector(matrix.row_vector(i).under_list()) for i in range(matrix.row_num())]
    # 因为行列式交换两行，数值 * -1 记录交换次数
    minus = 1

    # 开始高斯消元
    for i in range(matrix.row_num()):
        j = i
        # 查找主元
        while j < matrix.row_num():
            # 主元列从上往下第一个不为零的值就直接拿来当主元
            if not is_zero(m[j][i]):
                break

            if j == matrix.row_num() - 1:
                # 当前列全为零 那么行列式为0
                return 0
            j += 1

        if j != i:
            # 如果j!=i 交换两行
            m[i], m[j] = m[j], m[i]
            minus *= -1

        for k in range(i + 1, matrix.row_num()):
            # 主元列非主元的行依次消去,变为0
            m[k] = m[k] - m[i] * (m[k][i] / m[i][i])

    # 返回对角线的值的积
    return reduce(mul, [m[i][i] for i in range(matrix.row_num())]) * minus



